package com.ctshk.rpc.order.season.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.ProductType;
import com.ctshk.common.enums.SystemBusinessType;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.common.utils.SnowflakeIdWorker;
import com.ctshk.rpc.booking.enums.SupplierReserveTypeEnum;
import com.ctshk.rpc.booking.req.system.air.add.SupplierOrderSystemAirAddReq;
import com.ctshk.rpc.booking.req.system.air.add.SupplierSystemOrderAirAddReq;
import com.ctshk.rpc.booking.req.system.air.add.SupplierSystemOrderAirFlightAddReq;
import com.ctshk.rpc.booking.req.system.air.add.SupplierSystemOrderAirTicketAddReq;
import com.ctshk.rpc.booking.service.ISupplierOrderService;
import com.ctshk.rpc.order.air.service.IAirOrderService;
import com.ctshk.rpc.order.season.dto.SeasonOrderPayDTO;
import com.ctshk.rpc.order.season.dto.SeasonOrderTouristDataDTO;
import com.ctshk.rpc.order.season.dto.SeasonProductOrderAirDTO;
import com.ctshk.rpc.order.season.entity.SeasonOrder;
import com.ctshk.rpc.order.season.entity.SeasonProductOrderAir;
import com.ctshk.rpc.order.season.mapper.SeasonOrderMapper;
import com.ctshk.rpc.order.season.mapper.SeasonProductOrderAirMapper;
import com.ctshk.rpc.order.season.req.SeasonOrderReq;
import com.ctshk.rpc.order.season.service.ISeasonOrderTouristService;
import com.ctshk.rpc.order.season.service.ISeasonProductOrderAirService;
import com.ctshk.rpc.system.dto.UserDTO;
import com.ctshk.rpc.system.service.ISysUserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * <p>
 * 套票-订单-机票订单 服务实现类
 * </p>
 *
 * @author 杨林
 * @since 2021-03-24
 */
@DubboService
public class SeasonProductOrderAirServiceImpl extends ServiceImpl<SeasonProductOrderAirMapper, SeasonProductOrderAir> implements ISeasonProductOrderAirService {


    @Autowired
    private SeasonProductOrderAirMapper orderAirMapper;

    @Autowired
    private SeasonOrderMapper seasonOrderMapper;

    @Autowired
    private ISeasonOrderTouristService seasonOrderTouristService;

    @DubboReference
    private ISysUserService iSysUserService;

    @DubboReference
    private ISupplierOrderService supplierOrderService;

    @DubboReference
    private IAirOrderService airOrderService;

    @Override
    public void saveAirProduct(List<SeasonProductOrderAirDTO> airList, Long userId, Long orderId) {
        LocalDateTime now = LocalDateTime.now();
        List<SeasonProductOrderAir> list = airList.stream().map(
                airReq -> {
                    SeasonProductOrderAir air = EntityUtil.copy(airReq, SeasonProductOrderAir.class);
                    air.setCreateId(userId);
                    air.setGmtCreate(now);
                    air.setIsDeleted(IsDeletedCode.NO.getCode());
                    air.setSeasonOrderId(orderId);
                    air.setId(SnowflakeIdWorker.nextId());
                    if (null == airReq.getProductPrice() || BigDecimal.ZERO.compareTo(airReq.getProductPrice()) == 0) {
                        air.setPrice(BigDecimal.ZERO);
                    } else {
                        air.setPrice(airReq.getProductPrice());
                    }
                    return air;
                }
        ).collect(Collectors.toList());

        orderAirMapper.insertBatchSomeColumn(list);
    }


    /* @MethodName: 获取飞机票 订单信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/30 16:22
     **/
    @Override
    public List<SeasonProductOrderAirDTO> getOrderAirList(Long id) {
        List<SeasonProductOrderAirDTO> resultList = EntityUtil.copyList(
                orderAirMapper.selectList(
                        new QueryWrapper<SeasonProductOrderAir>().lambda()
                                .eq(SeasonProductOrderAir::getSeasonOrderId, id)
                                .eq(SeasonProductOrderAir::getIsDeleted, IsDeletedCode.NO.getCode())

                ), SeasonProductOrderAirDTO.class);

        return resultList;
    }


    /* @MethodName: 固定套票下供应商预订单
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/7 11:38
     **/
    @Override
    public void playSupplierOrder(Long orderId, TokenUser tokenUser) {
        SeasonOrder seasonOrder = getSeasonOrderById(orderId);
        //旅客信息
        List<SeasonOrderTouristDataDTO> touristList = seasonOrderTouristService.getTouristList(orderId);
        //是否是同一供应商（判读条件 主订单的 供应商id(就是负责人的部门id) 是否与机票一直）
        boolean ifEqualSupplier = true;
        //获取当前用户信息
        UserDTO user = iSysUserService.getUser(new UserDTO().setId(tokenUser.getId()));
        UserDTO chargeDto = iSysUserService.getUser(new UserDTO().setId(seasonOrder.getChargeUserId()));
        Long deptId = chargeDto.getDeptId();
        List<SeasonProductOrderAirDTO> airList = getOrderAirList(orderId);
        if (!CollectionUtils.isEmpty(airList)) {
            SeasonProductOrderAirDTO airDto1 = airList.get(0);

            if (!airDto1.getSupplierId().equals(deptId)) {
                ifEqualSupplier = false;
            }
            playSupplierAirOrder(seasonOrder, touristList, airList, airDto1.getSupplierId(), airDto1.getSupplierName(), user);
            if (!ifEqualSupplier) {//不是同一供应商 再次发起供应商预订单 只是供应商id 不同
                String depName = chargeDto.getDept();
                playSupplierAirOrder(seasonOrder, touristList, airList, deptId, depName, user);
            }
        }

    }

    /* @MethodName: 下飞机供应商预订单
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/8 19:52
     **/
    @Transactional(rollbackFor = Exception.class)
    public void playSupplierAirOrder(SeasonOrder seasonOrder, List<SeasonOrderTouristDataDTO> touristList, List<SeasonProductOrderAirDTO> airList, Long supplierId, String supplierName, UserDTO user) {

        SeasonProductOrderAirDTO airDto1 = airList.get(0);
        //发起供应商预订单
        SupplierOrderSystemAirAddReq supplierOrderSystemAirAddReq = new SupplierOrderSystemAirAddReq();
        //订单类型
        supplierOrderSystemAirAddReq.setOrderType(1);
        //供应商ID
        supplierOrderSystemAirAddReq.setSupplierId(supplierId);
        //供应商名称
        supplierOrderSystemAirAddReq.setSupplierName(supplierName);
        //供应商订单类型(1:普通订单,2:内部挂账订单)
        supplierOrderSystemAirAddReq.setSupplierOrderType("2");
        //业务类型
        supplierOrderSystemAirAddReq.setBusinessType(SystemBusinessType.AIR_TICKET.getCode());
        //预订类型
        supplierOrderSystemAirAddReq.setReserveTypeId(SupplierReserveTypeEnum.AIR.getId());
        //产品类型
        supplierOrderSystemAirAddReq.setProductType(ProductType.MANUAL_ENTRY.getCode());
        //资源所属部门ID(当前用户部门ID)
        supplierOrderSystemAirAddReq.setDepartmentId(user.getDeptId());
        //资源所属部门
        supplierOrderSystemAirAddReq.setDepartment(user.getDept());
        //销售单号(通用)
        supplierOrderSystemAirAddReq.setSaleNumber(seasonOrder.getOrderNumber());
        //产品编号(通用)???
        supplierOrderSystemAirAddReq.setProductNumber(String.valueOf(airDto1.getProductId()));
        //产品名称
        supplierOrderSystemAirAddReq.setProductName(seasonOrder.getProductName());
        //总金额
        supplierOrderSystemAirAddReq.setTotalFee(seasonOrder.getOrderAmount());
        //应付金额
        supplierOrderSystemAirAddReq.setPayableAmount(seasonOrder.getReceivableAmount());
        //TODO 付款类型ID,当值'内部挂账'时'scheduleId'不能为空,,枚举PayRefundMethod
        //        supplierOrderSystemAirAddReq.setPayTypeId();
        List<SupplierSystemOrderAirAddReq> systemOrderAirAddReqList = new LinkedList<>();
        for (SeasonProductOrderAirDTO airDto : airList) {
            SupplierSystemOrderAirAddReq orderAirAddReq = new SupplierSystemOrderAirAddReq();
            orderAirAddReq.setOrderId(seasonOrder.getId());
            //航空公司ID
            orderAirAddReq.setAirportCompanyId(airDto.getCompanyId());
            orderAirAddReq.setAirportCompany(airDto.getCompanyName());
            orderAirAddReq.setGoLocationJson(airDto.getDepCityName());
            orderAirAddReq.setDesLocationJson(airDto.getArrCityName());
            orderAirAddReq.setGoFlight(airDto.getFlightNumber());
            orderAirAddReq.setSuitablePeople(airDto.getSupplierName());
            List<SupplierSystemOrderAirTicketAddReq> airTicketList = new LinkedList<>();
            for (SeasonOrderTouristDataDTO dto : touristList) {
                SupplierSystemOrderAirTicketAddReq airTicketAddReq = new SupplierSystemOrderAirTicketAddReq();
                airTicketAddReq.setOrderId(seasonOrder.getId());
                airTicketAddReq.setStartTime(airDto.getDepTime());
                airTicketAddReq.setBackTime(airDto.getArrTime());
                // airTicketAddReq.setPositionId(airDto.getCabinClass());
                airTicketAddReq.setTouristId(dto.getId());
                airTicketAddReq.setTouristName(dto.getTouristName());
                airTicketAddReq.setTouristTypeId(dto.getTouristTypeId());
                airTicketAddReq.setTouristType(dto.getTouristType());
                airTicketAddReq.setCertificateTypeId(dto.getCertificatesTypeId());
                airTicketAddReq.setCertificateType(dto.getCertificatesType());
                airTicketAddReq.setCertificateNumber(dto.getCertificatesNumber());
                SupplierSystemOrderAirFlightAddReq airFlightAddReq = new SupplierSystemOrderAirFlightAddReq();
                airFlightAddReq.setOrderId(seasonOrder.getId());
                airFlightAddReq.setTicketId(dto.getId());
                airFlightAddReq.setGoLocationJson(airDto.getDepCityName());
                airFlightAddReq.setDesLocationJson(airDto.getArrCityName());
                airFlightAddReq.setFlightNumber(airDto.getFlightNumber());
                // airTicketAddReq.setSupplierSystemOrderAirFlightAddReq(airFlightAddReq);
                airTicketList.add(airTicketAddReq);
            }

            orderAirAddReq.setSupplierSystemOrderAirTicketAddReqList(airTicketList);
            systemOrderAirAddReqList.add(orderAirAddReq);
        }

        supplierOrderSystemAirAddReq.setSupplierSystemOrderAirAddReqList(systemOrderAirAddReqList);
        supplierOrderService.addSystemAir(supplierOrderSystemAirAddReq, user.getId());
    }

    /* @MethodName: 下飞机票的订单  生成订单号
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/8 11:28
     **/
    @Override
    public void playAirOrder(Long orderId, TokenUser user, List<SeasonOrderPayDTO> payList, List<SeasonOrderTouristDataDTO> touristList) {

    }

    /* @MethodName: 动态套票 下各自订单后 确认对应状态
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/14 10:57
     **/
    @Override
    public void changeAffirmState(Long orderId, Integer isAffirm) {
        UpdateWrapper<SeasonProductOrderAir> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(SeasonProductOrderAir::getOrderId, orderId);
        updateWrapper.lambda().set(SeasonProductOrderAir::getScheduledStatus, isAffirm);
        orderAirMapper.update(null, updateWrapper);
    }


    /* @MethodName: 退款状态
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/20 10:26
     **/
    @Override
    public void changeCancelOrderState(Long orderId, Integer cancelStatus) {
        UpdateWrapper<SeasonProductOrderAir> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(SeasonProductOrderAir::getOrderId, orderId);
        updateWrapper.lambda().set(SeasonProductOrderAir::getCancelStatus, cancelStatus);
        orderAirMapper.update(null, updateWrapper);
    }

    /* @MethodName: 锁丁机票的库存
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/14 13:45
     **/
    @Override
    public void lockInventoryAir(Long seasonOrderId, SeasonOrderReq req, TokenUser tokenUser) {
        //旅客信息
//        List<TouristTypeReq> touristList = req.getTouristTypeReqList();
//        List<Integer> airTourist = touristList.stream().map(
//                tourist -> tourist.getPassengerId()
//        ).collect(Collectors.toList());
//        Integer num = touristList.stream().mapToInt(TouristTypeReq::getPassengerNum).sum();
//        List<SeasonProductOrderAirDTO> list = req.getAirList();
//        if (!CollectionUtils.isEmpty(list)) {
//            for (SeasonProductOrderAirDTO airDTO : list) {
//                LockInventoryReq lockReq = new LockInventoryReq();
//                lockReq.setProductId(airDTO.getProductId());
//                lockReq.setNeedDate(airDTO.getDepTime().toLocalDate());
//                lockReq.setAirTouristTypeIds(airTourist);
//                lockReq.setPurchaseQuantity(num);
//                airOrderService.lockInventory(lockReq, tokenUser);
//            }
//        }
    }


    /* @MethodName: 释放库存
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/14 14:40
     **/
    @Override
    public void backStock(Long orderId, Long userId) {
        List<SeasonProductOrderAirDTO> airList = getOrderAirList(orderId);
        for (SeasonProductOrderAirDTO airDTO : airList) {
            airOrderService.releaseInventory(orderId, airDTO.getProductId());
        }
    }


    /* @MethodName: 固定套票下单 走 内部挂账形式
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/21 13:56
     **/
    @Override
    public void playInternalOrder(Long orderId, TokenUser user, List<SeasonOrderTouristDataDTO> touristList) {

    }

    public SeasonOrder getSeasonOrderById(Long id) {
        return seasonOrderMapper.selectById(id);
    }
}
